#ifndef _VECTEUR
#define _VECTEUR

#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<assert.h>

/**
*\file Vecteur.h
*\brief Fichier d'en-tête Vecteur.h. 
*
*Ce fichier d'en-tête gère tout ce qui concerne les opérations sur les vecteurs qui interviendront dans les déplacements du joueur. Il s'occupe aussi du passage direction <-> vecteur.
*
*\author Quentin LEONE
*\version version finale
*/

/**
* \struct vecteur
* \brief Structure du vecteur
* Cette structure porte les coordonnées d'une vecteur d'un espace de dimension 3.
*/
typedef struct 
{
	int x; /**< x, la première coordonnée du vecteur, doit être comprise entre 0 et la taille de l'espace*/
	int y; /**< y, la seconde coordonnée du vecteur, doit être comprise entre 0 et la taille de l'espace*/
	int z; /**< z, la troisième coordonnée du vecteur, doit être comprise entre 0 et la taille de l'espace*/
}vecteur;


/**
*\fn void afficheVecteur(vecteur v);
*\brief Affiche les coordonnées du vecteur
*\param [in] v : le vecteur à afficher
*/
void afficheVecteur(vecteur v);


/**
*\fn void remplaceVecteur(vecteur * v1, vecteur * v2);
*\brief Le vecteur v1 prend les coordonnées du vecteur v2
*\param [out] *v1 : pointeur sur le vecteur v1
*\param [in] *v2 : pointeur sur le vecteur v2
*/
void remplaceVecteur(vecteur * v1, vecteur * v2);



/**
*\fn int modulo(int x, int y);
*\brief Calcul le reste de la division euclidienne de x par y
*\param [in] x : un entier
*\param [in] y : le diviseur
*\return Un entier positif.
*\pre x et y doivent être positifs, y doit être non nuls.
*/
int modulo(int x, int y);


/**
*\fn int compareVecteur(vecteur * v1, vecteur * v2);
*\brief Compare deux vecteur et retourne 1 s'ils sont identiques, 0 sinon.
*\param [in] *v1 : pointeur sur le vecteur
*\param [in] *v2 : pointeur sur le second vecteur à comparer
*\return un booléen
*/
int compareVecteur(vecteur * v1, vecteur * v2);

/**
*\fn int getXVecteur(vecteur * vect);
* \brief récupère la première coordonné d'un vecteur
* \param [in] *vect : pointeur sur le vecteur qui nous intéresse
* \return un entier
* \pre aucune
*/
int getXVecteur(vecteur * vect);


/**
* \fn int getYVecteur(vecteur * vect);
* \brief récupè la seconde coordonné d'un vecteur
* \param [in] *vect : pointeur sur le vecteur qui nous intéresse
* \return un entier
* \pre aucune
*/
int getYVecteur(vecteur * vect);


/**
* \fn int getZVecteur(vecteur * vect);
* \brief récupè la troisième coordonné d'un vecteur
* \param [in] *vect : pointeur sur le vecteur qui nous intéresse
* \return un entier
* \pre aucune
*/
int getZVecteur(vecteur * vect);


/**
* \fn void setXVecteur(vecteur * vect, int m);
* \brief modifie la première coordonné d'un vecteur par m
* \param [in,out] *vect : pointeur sur le vecteur qui nous intéresse
* \param [in] m : un entier
* \pre aucune
*\post La première coordonnées est modifiée en m
*/
void setXVecteur(vecteur * vect, int m);


/**
* \fn void setYVecteur(vecteur * vect, int m);
* \brief modifie la deuxième coordonné d'un vecteur par m
* \param [in,out] *vect : pointeur sur le vecteur qui nous intéresse
* \param [in] m : un entier
* \pre aucune
*\post La première coordonnées est modifiée en m
*/
void setYVecteur(vecteur * vect, int m);


/**
* \fn void setZVecteur(vecteur * vect, int m);
* \brief modifie la troisième coordonné d'un vecteur par m
* \param [in,out] *vect : pointeur sur le vecteur qui nous intéresse
* \param [in] m : un entier
* \pre aucune
*\post La première coordonnées est modifiée en m
*/
void setZVecteur(vecteur * vect, int m);


/**
*\fn void directionVecteur(char direction, vecteur * v);
*\brief Retourne un vecteur selon la direction qui a été entrée. Par exemple, 'a' pour avant retournera (0,1,0), 'h' pour haut retournera (0,0,1) et 'b' pour bas retournera (0,0,-1). Le repère de base le repère classique. L'axe des x correspond à la gauche ou à la droite, celui des y correspond à avant ou arrière et celuyi des z correspond à haut ou bas.
*\param [in] direction : 'd' pour droite, 'g' pour gauche, 'a' pour avant, 'p' pour arrière, 'h' pour haut, 'b' pour bas
*\param [out] *v : pointeur sur le vecteur qui prendra la direction : respectivement (-1,0,0), (1,0,0), (0,1,0), (0,-1,0), (0,0,1), (0,0,-1)
*\pre La direction doit être l'une citée.
*\post Le vecteur doit prendre la valeur correspondante à la direction.
*/
void directionVecteur(char direction, vecteur * v);


/**
*\fn void changeSensVecteur(vecteur * v);
*\brief Change le sens du vecteur, v devient -v.
*\param [in,out] *v : pointeur sur le vecteur dont le sens changera
*/
void changeSensVecteur(vecteur * v);


/**
*\fn void addition(vecteur * v1, vecteur * v2, vecteur * v3, int n);
*\brief v3=v1+v2. Les coordonnées seront calculées modulo n si n est différent 0. Si n est nul, il n'y aura pas de calculs de modulo.
*\param [in] *v1 : pointeur sur un vecteur
*\param [in] *v2 : pointeur sur le vecteur
*\param [out] *v3 : pointeur sur le vecteur qui prendra la somme des autres.
*\param [in] n : taille du labyrinthe servant de calcul pour le modulo. Si n=0, le modulo n'est pas pris en compte
*\pre n doit être positif.
*/
void addition(vecteur * v1, vecteur * v2, vecteur * v3, int n);


/**
*\fn void soustraction(vecteur * v1, vecteur * v2, vecteur * v3, int n);
*\brief v3=v1-v2. Les coordonnées seront calculées modulo n si n est différent 0. Si n est nul, il n'y aura pas de calculs de modulo.
*\param [in] *v1 : pointeur sur un vecteur
*\param [in] *v2 : pointeur sur le vecteur
*\param [out] *v3 : pointeur sur le vecteur qui prendra la différence des autres.
*\param [in] n : taille du labyrinthe servant de calcul pour le modulo. Si n=0, le modulo n'est pas pris en compte
*\pre n doit être positif.
*/
void soustraction(vecteur * v1, vecteur * v2, vecteur * v3, int n);


/**
*\fn void produit(vecteur * v1, int k, vecteur * v2, int n);
*\brief v2=k*v1. Les coordonnées seront calculées modulo n si n est différent 0. Si n est nul, il n'y aura pas de calculs de modulo.
*\param [in] *v1 : pointeur sur un vecteur
*\param [in] k : entier
*\param [out] *v2 : pointeur sur le vecteur qui prendra lle produit de v par k
*\param [in] n : taille du labyrinthe servant de calcul pour le modulo. Si n=0, le modulo n'est pas pris en compte
*\pre n doit être positif.
*/
void produit(vecteur * v1, int k, vecteur * v2, int n);



/**
*\fn char sensDirection(vecteur * v2, vecteur * v1, int n);
*\brief Donne la direction qui permet d'aller de v1 à v2.
*\param [in] *v2 : pointeur sur le vecteur d'arrivé
*\param [in] *v1 : pointeur sur le vecteur de départ
*\param [in] n : taille du labyrinthe servant de calcul pour le modulo. Si n=0, le modulo n'est pas pris en compte
*\return on dit si v2 est a droite, a gauche, en haut, ... de v1 par un caractère (cf "void directionVecteur(char direction, vecteur * v);")
*\pre v2 et v1 doivent avoir une face en commun, ie une seule coordonnee differente
*/
char sensDirection(vecteur * v2, vecteur * v1, int n);


/**
*\fn void produitVectoriel(vecteur *v1,vecteur *v2,vecteur *v3);
*\brief Donne le produit vectoriel de v1 et v2 (dans ce sens).
*\param [in] *v1 : pointeur sur le premier vecteur du produit
*\param [in] *v2 : pointeur sur le second vecteur du produit
*\param [out] *v3 : pointeur sur le vecteur qui prendra le résultat
*\warning Le produit vectoriel est antisymétrique.
*/
void produitVectoriel(vecteur *v1,vecteur *v2,vecteur *v3);


/**
*\fn void rotationAxe(vecteur * v1, char axe, vecteur * v2, int angle);  
*\brief Donne le vecteur d'arrivé d'une rotation d'un angle autour d'un axe
*\param [in] *v1 : pointeur sur le v ecteur de départ
*\param [in] axe : caractère représentant un axe : x pour celui des x, y pour celui des y, z pour celui des z
*\param [out] *v2 : pointeur dur le vecteur d'arrivé
*\param [in] angle : angle de la rotation
*\pre angle doit être inférieur à 360 et superieur à -360 et l'axe doit être celui des x, y ou z.
*\post v2 doit avoir les coordonnées de retour
*/
void rotationAxe(vecteur * v1, char axe, vecteur * v2, int angle); 
#endif
